package com.bestcem.xm.user.service.impl;

import cn.hutool.core.collection.CollectionUtil;
import com.alibaba.excel.EasyExcelFactory;
import com.bestcem.xm.common.core.domain.web.ServiceResult;
import com.bestcem.xm.common.core.uitls.DateUtil;
import com.bestcem.xm.componet.filestorage.service.StorageService;
import com.bestcem.xm.user.config.properties.EmailNotificationProperties;
import com.bestcem.xm.user.config.properties.SettingProperties;
import com.bestcem.xm.user.constant.CommonConstant;
import com.bestcem.xm.user.constant.SystemConstant;
import com.bestcem.xm.user.enums.BooleanStatusEnum;
import com.bestcem.xm.user.enums.OrganizationStatusEnum;
import com.bestcem.xm.user.enums.PackageTypeEnum;
import com.bestcem.xm.user.enums.UserBookingTrackPlatformEnum;
import com.bestcem.xm.user.grpc.client.BpProjectGrpcService;
import com.bestcem.xm.user.grpc.client.IndustryGrpcService;
import com.bestcem.xm.user.grpc.client.OmUserGrpcService;
import com.bestcem.xm.user.grpc.client.PackageGrpcService;
import com.bestcem.xm.user.grpc.client.dto.*;
import com.bestcem.xm.user.grpc.service.param.ListOrgByPageParam;
import com.bestcem.xm.user.grpc.service.param.PageParam;
import com.bestcem.xm.user.service.*;
import com.bestcem.xm.user.service.dto.PageResponseDTO;
import com.bestcem.xm.user.service.dto.user.*;
import com.bestcem.xm.user.util.business.FileUtils;
import com.bestcem.xm.user.util.business.UserUtil;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.io.File;
import java.time.LocalDateTime;
import java.util.*;
import java.util.stream.Collectors;

/**
 * 用户定时任务业务层
 *
 * @author YiFang <yifang.zhang@idiaoyan.com>
 * @version v1.0
 * @date 2022/8/17 21:10
 */
@Slf4j
@Service
public class UserJobServiceImpl implements UserJobService {

    private static final Logger EMAIL_LOG = LoggerFactory.getLogger("EmailErrorLog");

    @Resource
    private UserOrgBusinessService userOrgBusinessService;

    private static final String DATEFORMAT = "yyyy年MM月dd日HH时mm分ss秒";

    @Autowired
    private SettingProperties settingProperties;

    @Autowired
    private UserBookingTrackService userBookingTrackService;

    @Autowired
    private BpProjectGrpcService bpProjectGrpcService;

    @Autowired
    private MailService mailService;

    @Autowired
    private EmailNotificationProperties emailNotificationProperties;

    @Autowired
    private OrganizationService organizationService;

    @Autowired
    private PackageGrpcService packageGrpcService;

    @Autowired
    private IndustryGrpcService industryGrpcService;

    @Value("${spring.profiles.active:test}")
    private String appEnv;

    //@Resource
    //private OrganizationMessageSender organizationSender;

    @Resource
    private UserBusinessService userBusinessService;


    @Autowired
    private OmUserGrpcService omUserGrpcService;


    @Autowired
    private UserUtil userUtil;


    /*@Resource
    private OssService ossService;*/

    @Autowired
    private StorageService storageService;

    private String getEmailOssPath() {
        //return ossService.getUrlPrefix() + "email/";
        return storageService.getPropertiesValueBy(null, "domain") + storageService.getPropertiesValueBy(null, "base-path") + "email/";
    }

    @Override
    public void executeCreatePreOrgJob() {
        try {
            if (log.isInfoEnabled()) {
                log.info("[USER] 预创建注册公司定时任务开始");
            }
            userOrgBusinessService.createPreOrgForRegister();
            if (log.isInfoEnabled()) {
                log.info("[USER] 预创建注册公司定时任务结束");
            }
        } catch (Throwable e) {
            log.error("[USER] {} 预创建注册公司定时任务失败; ErrorMsg: {}", e.getMessage(), e);
            EMAIL_LOG.error("[USER] {} 预创建注册公司定时任务失败,ErrorMsg: {}", e.getMessage(), e);
        }
    }

    @Override
    public void executeExportDailyVisitorJob() {
        // 附件列表
        Map<String, File> enclosureFiles = new HashMap<>();
        try {
            if (log.isInfoEnabled()) {
                log.info("[USER] 导出每日数据定时任务开始");
            }
            // 每天早上八点半执行定时任务
            // 导出昨天一整天倍市得官网的访客数据和答卷数据到Excel并发送邮件给负责人
            // 获取今天和昨天的时间
            Calendar calendar = Calendar.getInstance();
            calendar.set(Calendar.HOUR_OF_DAY, 0);
            calendar.set(Calendar.MINUTE, 0);
            calendar.set(Calendar.SECOND, 0);
            calendar.set(Calendar.MILLISECOND, 0);
            Date today = calendar.getTime();
            calendar.add(Calendar.DAY_OF_MONTH, -1);
            Date yesterday = calendar.getTime();
            // 获取昨日的访客数据
            ServiceResult<List<UserBookingTrackDTO>> bookingTracksResult = userBookingTrackService.findAndGenFileByCreateTimeInterval(yesterday, today);
            List<UserBookingTrackDTO> bookingTracks = bookingTracksResult.getData();
            String visitorFileName = DateUtil.convertDteToString(today, "yyyy年MM月dd日") + "_倍市得访客数据" + FileUtils.XLSX_SUFFIX;
            File visitorFile = generateUserVisitorFile(bookingTracks, visitorFileName);
            if (Objects.nonNull(visitorFile)) {
                enclosureFiles.put(visitorFileName, visitorFile);
            }
            String rspdFileName = DateUtil.convertDteToString(today, "yyyy年MM月dd日") + "_倍市得答卷数据" + FileUtils.XLSX_SUFFIX;
            // 获取并生成昨日答卷数据文件流
            File rspdFile = generateRspdFile(rspdFileName);
            if (Objects.nonNull(rspdFile)) {
                enclosureFiles.put(rspdFileName, rspdFile);
            }
            // 发送邮件给市场、销售、开发
            String subject = settingProperties.getXmName() + "_" + DateUtil.convertDteToString(today, "yyyy年MM月dd日") + "_倍市得数据";
            List<String> emails;
            if (!appEnv.equals("prod")) {
                emails = emailNotificationProperties.getDeveloperEmails();
            } else {
                emails = emailNotificationProperties.getVisitorDataEmails();
            }
            List<String> ccEmails = emailNotificationProperties.getCcEmails();
            mailService.sendEmailAndEnclosure(emails.toArray(new String[emails.size()]),
                    CollectionUtil.isNotEmpty(ccEmails) ? ccEmails.toArray(new String[ccEmails.size()]) : null, subject, "见附件", enclosureFiles);
            if (log.isInfoEnabled()) {
                log.info("[USER] {} 导出每日数据定时邮件已发送，收件人 {}，抄送人：{}", emails, ccEmails);
            }
        } catch (Throwable e) {
            log.error("[USER] {} 导出每日数据定时任务失败; ErrorMsg: {}", e.getMessage(), e);
            EMAIL_LOG.error("[USER] {} 导出每日数据定时任务失败,ErrorMsg: {}", e.getMessage(), e);
            // 异常通知开发
            mailService.sendEmail(emailNotificationProperties.getDeveloperEmails().toArray(new String[0]),
                    settingProperties.getXmName() + "_倍市得数据异常", e.getMessage());
        } finally {
            // 删除临时生成的文件
            enclosureFiles.forEach((key, value) -> FileUtils.safeDelete(value));
        }
        if (log.isInfoEnabled()) {
            log.info("[USER] 导出每日数据定时任务结束");
        }
    }

    @Override
    public void executePackageDemotionJob() {
        if (log.isInfoEnabled()) {
            log.info("[USER] 公司套餐降级任务定时任务开始");
        }
        // async_org_package_demotion
        // 试用套餐降级为正式套餐
        ServiceResult<List<OrganizationDTO>> trialResult = organizationService.getExpirePackOrg("trial");
        if (trialResult.isSuccess() && CollectionUtils.isNotEmpty(trialResult.getData())) {
            List<OrganizationDTO> organizationList = trialResult.getData();
            for (OrganizationDTO organizationDTO : organizationList) {
                // 租户修改套餐 通知java
                //organizationSender.orgPackUpdate(organizationDTO.getOrgId(), organizationDTO.getTrialPackageId(), organizationDTO.getFormalPackageId());
                //if (log.isInfoEnabled()) {
                //    log.info("[USER]定时任务执行， {}公司试用套餐开始降级（试用套餐降级为正式套餐）,orgId={}", organizationDTO.getCode(), organizationDTO.getOrgId());
                //}
                organizationDTO.setOrgId(organizationDTO.getOrgId());
                organizationDTO.setPackageId(organizationDTO.getFormalPackageId());
                organizationDTO.setPackageExpireTime(organizationDTO.getFormalExpireTime());
                organizationDTO.setUpdateTime(new Date());
                organizationDTO.setTrialPackageId(null);
                organizationService.updateByPrimaryKey(organizationDTO);
                if (log.isInfoEnabled()) {
                    log.info("[USER]定时任务执行， {}公司试用套餐降级完成（试用套餐降级为正式套餐）,orgId={}", organizationDTO.getCode(), organizationDTO.getOrgId());
                }
            }
        }

        // 正式套餐降级为免费套餐
        // 获取免费套餐
        PackageDTO freePackageDTO = packageGrpcService.getByType(PackageTypeEnum.FREE.getType());
        ServiceResult<List<OrganizationDTO>> formalResult = organizationService.getExpirePackOrg("formal");
        if (formalResult.isSuccess()) {
            List<OrganizationDTO> organizationList = formalResult.getData();
            for (OrganizationDTO organizationDTO : organizationList) {
                // 租户修改套餐 通知java
                //organizationSender.orgPackUpdate(organizationDTO.getOrgId(), organizationDTO.getFormalPackageId(), freePackageDTO.getPackageId());
                //if (log.isInfoEnabled()) {
                //    log.info("[USER]定时任务执行， {}公司试用套餐开始降级（正式套餐降级为免费套餐）,orgId={}", organizationDTO.getCode(), organizationDTO.getOrgId());
                //}
                // 原organization套餐id
                String oldPackId = organizationDTO.getFormalPackageId();
                if (freePackageDTO.getPackageId().equals(oldPackId)) {
                    continue;
                }
                log.info("[USER]定时任务执行,org_id={}--org_code={}----开始降级为基础版套餐", organizationDTO.getOrgId(), organizationDTO.getCode());
                String oldFormalExpireTime = DateUtil.convertDteToString(organizationDTO.getFormalExpireTime(), "yyyy-MM-dd");
                organizationDTO.setPackageId(freePackageDTO.getPackageId());
                organizationDTO.setFormalPackageId(freePackageDTO.getPackageId());
                organizationDTO.setPackageExpireTime(DateUtil.getDate("2099-12-31"));
                organizationDTO.setFormalExpireTime(DateUtil.getDate("2099-12-31"));
                organizationDTO.setTrialPackageId(null);
                // 注意：这里没有按照python原有代码逻辑把使用套餐过期时间也置为null，因为试用套餐过期禁用需要用到 试用过期时间字段，故暂不清空
                organizationDTO.setUpdateTime(new Date());
                organizationService.updateByPrimaryKey(organizationDTO);
                packageGrpcService.deletePackageCacheByOrgId(organizationDTO.getOrgId());
                // 发送邮件和短信 延时任务 9小时
                //long expireTime = System.currentTimeMillis() + 9 * 60 * 60 * 1000;
                //PackageExpireMessage message = new PackageExpireMessage();
                //message.setOrgId(organizationDTO.getOrgId());
                //message.setFormalPackageId(oldPackId);
                //message.setCode(organizationDTO.getCode());
                //message.setName(organizationDTO.getName());
                //message.setFormalExpireTime(oldFormalExpireTime);
                //organizationSender.sendDelayMq(message, new Date(expireTime), "套餐到期");
                if (log.isInfoEnabled()) {
                    log.info("[USER]定时任务执行， {}公司试用套餐降级完成 （正式套餐降级为免费套餐）,orgId={}", organizationDTO.getCode(), organizationDTO.getOrgId());
                }
            }
        }
        if (log.isInfoEnabled()) {
            log.info("[USER] 公司套餐降级任务定时任务结束");
        }
    }

    @Override
    public void executePackageTemporaryReminderJob() {
        if (log.isInfoEnabled()) {
            log.info("[USER]  公司套餐30天临期提醒定时任务开始");
        }
        //  查询30天后即将过期的套餐，发送短信或者邮件提醒
        String url = settingProperties.getSassServerUrl() + "/version";
        LocalDateTime currentTime = DateUtil.getCurrentTime();
        List<Integer> orgStatusList = Arrays.asList(OrganizationStatusEnum.ACTIVATED.getStatus(),
                OrganizationStatusEnum.EXPIRED.getStatus(),
                OrganizationStatusEnum.INACTIVATED.getStatus());
        List<OrganizationDTO> organizationDTOList = organizationService.getByfomalExpiryTime(currentTime, orgStatusList);
        for (OrganizationDTO org : organizationDTOList) {
            PackageDTO packageDTO = packageGrpcService.getById(org.getFormalPackageId());
            // 获取系统管理员
            ServiceResult<UserDTO> adminUserResult = userBusinessService.getAdminUserByOrgId(org.getOrgId());
            UserDTO userDTO = adminUserResult.getData();
            if (log.isInfoEnabled()) {
                log.info("[USER]定时任务， {}公司临期提醒，orgId={}", org.getCode(), org.getOrgId());
            }
            // 非生产，非内部
            if (!SystemConstant.PROD_APP_ENV.equals(settingProperties.getAppEnv()) && !userUtil.checkUserIsInner(userDTO.getPhone(), userDTO.getEmail(), "")) {
                continue;
            }
            if (StringUtils.isNotBlank(userDTO.getPhone())) {
                Map<String, Object> map = new HashMap<>();
                map.put("mobile", userDTO.getPhone());
                map.put("name", userDTO.getName());
                map.put("pack_name", packageDTO.getOutName());
                map.put("pack_data", DateUtil.convertDteToString(org.getFormalExpireTime(), DateUtil.YYYY_MM_DD));
                map.put("url", url);
                map.put("type", "将于");
                map.put("time", DateUtil.convertDteToString(new Date(), DateUtil.YYYY_MM_DD));
                map.put("telephone", settingProperties.getBestHotline());
                map.put("org_code", org.getCode());
                map.put("notify_title", "版本临期");
                map.put("org_id", org.getOrgId());
                // 短信发送
                organizationService.notifyTemporaryReminderBySms(userDTO.getPhone(), map);
            }
            if (StringUtils.isNotBlank(userDTO.getEmail())) {
                Map<String, Object> emailMap = new HashMap<>();
                emailMap.put("email", userDTO.getEmail());
                emailMap.put("name", userDTO.getName());
                emailMap.put("org_code", org.getCode());
                emailMap.put("org_name", org.getName());
                emailMap.put("pack_name", packageDTO.getOutName());
                emailMap.put("pack_data", DateUtil.convertDteToString(org.getFormalExpireTime(), DateUtil.YYYY_MM_DD));
                emailMap.put("url", url);
                emailMap.put("type", "将于");
                emailMap.put("time", DateUtil.convertDteToString(new Date(), DateUtil.YYYY_MM_DD));
                emailMap.put("telephone", CommonConstant.BEST_HOTLINE);
                emailMap.put("subject", "即将");
                emailMap.put("email_oss_path", getEmailOssPath());
                emailMap.put("notify_title", "版本临期");
                emailMap.put("org_id", org.getOrgId());
                // 邮件发送
                organizationService.notifyTemporaryReminderByEmail(userDTO.getEmail(), emailMap);
            }

            RelationDTO orgRelatedOp = omUserGrpcService.getOrgRelatedOp(org.getOrgId());
            if (StringUtils.isNotBlank(orgRelatedOp.getId())) {
                OmUserDTO omUserDTO = omUserGrpcService.getOmUser(orgRelatedOp.getId());
                Map<String, Object> emailMap = new HashMap<>();
                emailMap.put("email", omUserDTO.getEmail());
                emailMap.put("name", userDTO.getName());
                emailMap.put("org_code", org.getCode());
                emailMap.put("org_name", org.getName());
                emailMap.put("pack_name", packageDTO.getOutName());
                emailMap.put("pack_data", DateUtil.convertDteToString(org.getFormalExpireTime(), DateUtil.YYYY_MM_DD));
                emailMap.put("url", url);
                emailMap.put("type", "将于");
                emailMap.put("time", new Date());
                emailMap.put("telephone", settingProperties.getBestHotline());
                emailMap.put("subject", "即将");
                emailMap.put("email_oss_path", getEmailOssPath());
                emailMap.put("notify_title", "版本临期");
                emailMap.put("org_id", org.getOrgId());
                // 邮件发送
                organizationService.notifyTemporaryReminderByEmail(omUserDTO.getEmail(), emailMap);
            }
        }
        if (log.isInfoEnabled()) {
            log.info("[USER]  公司套餐30天临期提醒定时任务结束");
        }
    }

    @Override
    public void executeUploadGrowingioJob() {
        try {
            if (log.isInfoEnabled()) {
                log.info("[USER] 每三个月向growingio上传一次登录用户变量定时任务开始");
            }
            // 查询公司
            OrganizationDTO organizationDTO = new OrganizationDTO();
            List<OrganizationDTO> organizationDTOList = organizationService.selectBySelective(organizationDTO).getData();
            if (log.isInfoEnabled()) {
                log.info("[USER] growingio上传organization数量：{}", organizationDTOList.size());
            }
            // 公司套餐map
            Map<String, PackageDTO> packageMap = new HashMap<>();
            for (OrganizationDTO organization : organizationDTOList) {
                // 设置公司套餐
                PackageDTO packageDTO = packageMap.get(organization.getPackageId());
                if (packageDTO == null) {
                    packageDTO = packageGrpcService.getById(organization.getPackageId());
                    packageMap.put(organization.getPackageId(), packageDTO);
                }
                // 上传用户growingio
                userBusinessService.uploadGrowingio(organization, packageDTO);
            }
            if (log.isInfoEnabled()) {
                log.info("[USER] 每三个月向growingio上传一次登录用户变量定时任务结束");
            }
        } catch (Throwable e) {
            log.error("[USER] {} 每三个月向growingio上传一次登录用户变量定时任务失败; ErrorMsg: {}", e.getMessage(), e);
            EMAIL_LOG.error("[USER] {} 每三个月向growingio上传一次登录用户变量定时任务失败,ErrorMsg: {}", e.getMessage(), e);
        }
        if (log.isInfoEnabled()) {
            log.info("[USER] 每三个月向growingio上传一次登录用户变量定时任务结束");
        }
    }

    /**
     * 根据用户埋点数据列表生成访客数据文件
     *
     * @param bookingTracks 埋点数据列表
     * @param fileName      文件名
     * @return java.io.File
     * @author cuiqiongyu <qiongyu.cui@idiaoyan.cn>
     * @date 2022/06/02 09:22
     */
    private File generateUserVisitorFile(List<UserBookingTrackDTO> bookingTracks, String fileName) {
        File file = new File(fileName);
        if (file.exists()) {
            FileUtils.safeDelete(file);
        }
        try {
            // 构建表格内容
            List<UserBookingTrackExportDTO> content = new ArrayList<>();
            if (CollectionUtils.isEmpty(bookingTracks)) {
                content.add(new UserBookingTrackExportDTO());
            } else {
                for (UserBookingTrackDTO bookingTrack : bookingTracks) {
                    UserBookingTrackExportDTO dto = new UserBookingTrackExportDTO();
                    dto.setTraceId(bookingTrack.getTraceId());
                    dto.setRequestTime(DateUtil.convertDteToString(bookingTrack.getCreateTime(), DATEFORMAT));
                    dto.setUtmSource(bookingTrack.getUtmSource());
                    dto.setPlan(filter(bookingTrack.getPlan()));
                    dto.setDevice(bookingTrack.getDevice());
                    dto.setClickFlag(BooleanStatusEnum.YES.getStatus().equals(bookingTrack.getClickFlag()) ? "是" : "否");
                    dto.setSubmitFlag(BooleanStatusEnum.YES.getStatus().equals(bookingTrack.getSubmitFlag()) ? "是" : "否");
                    dto.setName(bookingTrack.getName());
                    dto.setPhone(bookingTrack.getPhone());
                    dto.setEmail(bookingTrack.getEmail());
                    dto.setOrgName(bookingTrack.getOrgName());
                    dto.setIndustry(bookingTrack.getIndustry());
                    UserBookingTrackPlatformEnum platform = UserBookingTrackPlatformEnum.getByType(bookingTrack.getPlatform());
                    dto.setPlatform(Objects.isNull(platform) ? "空" : platform.getDesc());
                    dto.setBlurFlag(BooleanStatusEnum.YES.getStatus().equals(bookingTrack.getBlurFlag()) ? "是" : "否");
                    content.add(dto);
                }
            }
            EasyExcelFactory
                    .write(fileName, UserBookingTrackExportDTO.class)
                    .sheet(fileName)
                    .doWrite(content);
        } catch (Exception e) {
            log.error("[USER] generateUserVisitorFile异常，e={} ", e);
            // 异常通知开发
            mailService.sendEmail(emailNotificationProperties.getDeveloperEmails().toArray(new String[0]),
                    settingProperties.getXmName() + "_倍市得数据异常", e.getMessage());
        }
        return file;
    }

    /**
     * 获取昨日答卷数据
     *
     * @param fileName 文件名
     * @return java.io.InputStream
     * @author cuiqiongyu <qiongyu.cui@idiaoyan.cn>
     * @date 2022/07/08 17:14
     */
    private File generateRspdFile(String fileName) {
        File file = new File(fileName);
        if (file.exists()) {
            FileUtils.safeDelete(file);
        }
        try {
            // 构建表格内容
            List<OrganizationRspdDTO> content = new ArrayList<>();

            // 分页查询公司列表信息
            int page = 1;
            int pageSize = 500;
            ListOrgByPageParam pageParam = new ListOrgByPageParam();
            pageParam.setPageParam(new PageParam(page, pageSize));
            pageParam.setStatuses(Arrays.asList(OrganizationStatusEnum.ACTIVATED.getStatus(),
                    OrganizationStatusEnum.EXPIRED.getStatus(),
                    OrganizationStatusEnum.INACTIVATED.getStatus()));
            Date today = new Date();
            Date yesterday = DateUtil.getYesterdayDate(today);

            PageResponseDTO<OrganizationDTO> organizations = organizationService.listOrganizationsByPage(pageParam).getData();
            // 套餐名字map缓存
            Map<String, String> packageNameMap = new HashMap<>();
            // 行业名字map缓存
            Map<String, String> industryNameMap = new HashMap<>();
            List<OrganizationDTO> rows = organizations.getRows();
            if (CollectionUtils.isEmpty(rows)) {
                content.add(new OrganizationRspdDTO());
            } else {
                Long total = organizations.getTotal();
                int totalPage = (int) (total + pageSize - 1) / pageSize;
                content.addAll(handlerRspdData(rows, packageNameMap, industryNameMap, yesterday, today));
                if (totalPage > 1) {
                    for (int i = 2; i <= totalPage; i++) {
                        pageParam.setPageParam(new PageParam(i, pageSize));
                        PageResponseDTO<OrganizationDTO> organizationsTemp = organizationService.listOrganizationsByPage(pageParam).getData();
                        content.addAll(handlerRspdData(organizationsTemp.getRows(), packageNameMap, industryNameMap, yesterday, today));
                    }
                }
            }
            EasyExcelFactory
                    .write(fileName, OrganizationRspdDTO.class)
                    .sheet(fileName)
                    .doWrite(content);
        } catch (Exception e) {
            e.printStackTrace();
            // 异常通知开发
            mailService.sendEmail(emailNotificationProperties.getDeveloperEmails().toArray(new String[0]),
                    settingProperties.getXmName() + "_倍市得数据异常", e.getMessage());
        }
        return file;
    }

    /**
     * 处理问卷数据
     *
     * @param rows      公司列表
     * @param startDate 开始时间
     * @param endDate   结束时间
     * @return java.util.List<com.bestcem.xm.user.service.dto.user.OrganizationRspdDTO>
     * @author cuiqiongyu <qiongyu.cui@idiaoyan.cn>
     * @date 2022/07/08 18:06
     */
    private List<OrganizationRspdDTO> handlerRspdData(List<OrganizationDTO> rows, Map<String, String> packageNameMap, Map<String, String> industryNameMap, Date startDate, Date endDate) {
        List<OrganizationRspdDTO> rspds = new ArrayList<>();
        if (CollectionUtils.isEmpty(rows)) {
            return rspds;
        }
        // 公司问卷答卷数map
        Map<String, ProjectDataDTO> projectDataDTOMap = new HashMap<>();
        List<String> orgIds = rows.stream().map(OrganizationDTO::getOrgId).collect(Collectors.toList());
        // 查询问卷答卷数
        List<ProjectDataDTO> projectDataDTOS = bpProjectGrpcService.listProjectCountsByCreateTime(orgIds, startDate, endDate);
        if (CollectionUtils.isNotEmpty(projectDataDTOS)) {
            projectDataDTOMap = projectDataDTOS.stream().collect(Collectors.toMap(ProjectDataDTO::getOrgId, p -> p));
        }
        for (OrganizationDTO row : rows) {
            OrganizationRspdDTO dto = new OrganizationRspdDTO();
            dto.setOrgCode(row.getCode());
            dto.setOrgName(row.getName());
            dto.setCreateTime(DateUtil.convertDteToString(row.getCreateTime(), DateUtil.NORM_DATETIME_PATTERN));
            String packageName = packageNameMap.get(row.getPackageId());
            if (Objects.isNull(packageName) && Objects.nonNull(row.getPackageId())) {
                PackageDTO pack = packageGrpcService.getById(row.getPackageId());
                if (null != pack) {
                    packageName = pack.getName();
                    packageNameMap.put(row.getPackageId(), packageName);
                }
            }
            dto.setPackName(packageName);
            String industryName = industryNameMap.get(row.getIndustryId());
            if (Objects.isNull(industryName)) {
                IndustryDTO industryDTO = industryGrpcService.getById(row.getIndustryId());
                if (null != industryDTO) {
                    industryName = industryDTO.getName();
                    industryNameMap.put(row.getIndustryId(), industryName);
                }
            }
            dto.setIndustryName(industryName);
            dto.setExpireTime(DateUtil.convertDteToString(row.getPackageExpireTime(), DateUtil.NORM_DATETIME_PATTERN));

            ProjectDataDTO projectDataDTO = projectDataDTOMap.get(row.getOrgId());
            dto.setCreateProjectNum(Objects.isNull(projectDataDTO) || Objects.isNull(projectDataDTO.getProjectCount())
                    ? "0" : projectDataDTO.getProjectCount().toString());
            dto.setRspdNum(Objects.isNull(projectDataDTO) || Objects.isNull(projectDataDTO.getRespondentCount())
                    ? "0" : projectDataDTO.getRespondentCount().toString());
            rspds.add(dto);
        }

        return rspds;
    }

    /**
     * 过滤ascii中不可见的字符
     * python: commons.common_utils.strip_control_characters
     *
     * @param content 原字符串
     * @return java.lang.String 过滤后的结果
     * @author cuiqiongyu <qiongyu.cui@idiaoyan.cn>
     * @date 2022/06/02 16:49
     */
    public static String filter(String content) {
        if (StringUtils.isNotBlank(content)) {
            char[] contentCharArr = content.toCharArray();
            StringBuilder buf = new StringBuilder();
            for (int i = 0; i < contentCharArr.length; i++) {
                // 0x20 为ASCII中第32个字符,0xA为换行，0xD为回车
                if (contentCharArr[i] > 0x20 || contentCharArr[i] == 0xA || contentCharArr[i] == 0xD) {
                    buf.append(contentCharArr[i]);
                }
            }
            return buf.toString();
        }
        return "";
    }
}
